package com.ryskoo.controller.product;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ryskoo.catering.orderdetail.service.IOrderDetailService;
import com.ryskoo.catering.productattr.domain.ProductAttrPO;
import com.ryskoo.catering.productattr.service.IProductAttrService;
import com.ryskoo.catering.productattrvalue.domain.ProductAttrValuePO;
import com.ryskoo.catering.productcate.domain.ProductCategoryPO;
import com.ryskoo.catering.productcate.service.IProductCategoryService;
import com.ryskoo.catering.productimage.domain.ProductImagePO;
import com.ryskoo.catering.productimage.service.IProductImageService;
import com.ryskoo.catering.productmain.domain.ProductMainPO;
import com.ryskoo.catering.productmain.service.IProductMainService;
import com.ryskoo.catering.productspec.domain.ProductSpecPO;
import com.ryskoo.catering.vendortemplaterel.domain.VendorTemplateRelPO;
import com.ryskoo.catering.vendortemplaterel.service.IVendorTemplateRelService;
import com.ryskoo.catering.vendortemplatereldetail.domain.VendorTemplateRelDetailPO;
import com.ryskoo.customer.vendor.domain.VendorPO;
import com.ryskoo.customer.vendor.service.IVendorService;
import com.ryskoo.framework.core.bean.Pager;
import com.ryskoo.framework.core.bean.QueryConditionEnum;
import com.ryskoo.framework.core.bean.QueryMessageDTO;
import com.ryskoo.framework.core.bean.ReturnCodeEnum;
import com.ryskoo.framework.core.bean.ReturnMessageDTO;
import com.ryskoo.framework.core.controller.BasicHandler;
import com.ryskoo.framework.core.utils.LoginUtil;
import com.ryskoo.util.FastDFSClient;
import com.ryskoo.util.ImageUtils;
import com.ryskoo.util.LocalUploaderClient;
import com.ryskoo.util.ProductInteractiveDTO;

@Controller("caterProductController")
@RequestMapping("/vendor/cater/product")
public class ProductController extends BasicHandler<ProductMainPO> {

    private static final String TEMPLATE_PATH = "system/product";

    private static final String MODULE_NAME = "Product";
    /**
     * 基类构造方法.
     */
    public ProductController() {
        super(TEMPLATE_PATH, MODULE_NAME);
    }

    private IProductMainService productService;

 // FastDFS前缀
    @Value("${fdfs.ip.pre}")
    public String fdfsIpPre;

    @Autowired
    private FastDFSClient fastDFSClient;
    @Autowired
    private LocalUploaderClient localUploaderClient;
    @Autowired
    private IProductAttrService productAttrService;
    @Autowired
    private IProductCategoryService productCategoryService;
    @Autowired
    private IProductImageService productImageService;
    @Autowired
    private IOrderDetailService orderDetailService;
    @Autowired
    private IVendorService vendorService;
    @Autowired
    private IVendorTemplateRelService vendorTemplateRelService;
    
    /** 压缩图片的临时路径 */
    @Value("${resizeFilePath}")
    private String resizeFilePath;

    /** 是否上传到图片服务器，如果是否的话，就上传到tomcat中 */
    @Value("${uploadToServer}")
    public Boolean uploadToServer;

    @Value("${imageUrl}")
    public String imageUrl;

    @Value("${localPath}")
    public String localPath;

    /**
     * 消费者注入
     *
     * @param productService 消费者基类
     */
    @Autowired
    protected void setService(IProductMainService productService) {
        this.productService = productService;
        super.setService(productService);
    }


    @Override
	protected void buildListPageData(Model model, HttpServletRequest request) {
		String vendorId = LoginUtil.getLoginVendorUuid();
		model.addAttribute("vendorId", vendorId);
	}


	@Override
	protected void buildAddPageData(Model model, HttpServletRequest request) {
		String vendorId = LoginUtil.getLoginVendorUuid();
		model.addAttribute("vendorId", vendorId);
		// 1.加载该商户下的分类
        buildCateData(model,vendorId);
        // 2.将该商户支持的属性传到前台
        buildTemplateAttrData(model,vendorId);
        super.buildAddPageData(model, request);
	}


	@Override
	protected void buildEditPageData(Model model, ProductMainPO po, HttpServletRequest request) {
		String vendorId = LoginUtil.getLoginVendorUuid();
		model.addAttribute("vendorId", vendorId);
		// 1.加载该商户下的分类
        buildCateData(model,po.getVendorUuid());
        super.buildEditPageData(model, po, request);
	}


	/**
     * 查询该商户关联的属性模板及启用的属性值集合传到前台
     * @param model
     * @param vendorUuid
     */
    private void buildTemplateAttrData(Model model, String vendorUuid) {
        List<VendorTemplateRelPO> attrList = vendorTemplateRelService.getAllRelsByVendorUuid(vendorUuid, true, true);
        List<ProductAttrPO> list = new ArrayList<>();
        if (attrList != null && attrList.size() > 0) {
        	int index = 0;
            for (VendorTemplateRelPO dto:attrList) {
                ProductAttrPO attr = new ProductAttrPO();
                attr.setName(dto.getAttrName());
                attr.setSpec(dto.isSpec());
                attr.setStatus(dto.isStatus());
                attr.setPosition(index++);
                List<VendorTemplateRelDetailPO> details = dto.getDetails();
                List<ProductAttrValuePO> values = new ArrayList<>();
                for (VendorTemplateRelDetailPO detail:details) {
                    ProductAttrValuePO attrValue = new ProductAttrValuePO();
                    attrValue.setValue(detail.getValue());
                    attrValue.setPosition(detail.getPosition());
                    values.add(attrValue);
                }
                attr.setProductAttrValueList(values);
                list.add(attr);
            }
        }
        model.addAttribute("attrList",list);
    }

    /**
     * 查询普通商品分类集合传到前台
     * @param model
     * @param vendorUuid
     */
    private void buildCateData(Model model, String vendorUuid) {
        QueryMessageDTO qm = new QueryMessageDTO();
        Map<String,Map<String,Object>> conditions = new HashMap<>();
        Map<String,Object> vendorCondition = new HashMap<>();
        vendorCondition.put("operation","EQ");
        vendorCondition.put("value",vendorUuid);
        Map<String,Object> typeCondition = new HashMap<>();
        typeCondition.put("operation","EQ");
        typeCondition.put("value","1");
        conditions.put("vendorUuid",vendorCondition);
        conditions.put("type",typeCondition);
        qm.setQueryParams(conditions);
        List<ProductCategoryPO> list = productCategoryService.queryByCondition(qm);
        model.addAttribute("normalCateList",list);
    }
    
    
	/**
     * 新增菜品
     *
     * @param dto
     * @return
     */
    @PostMapping("/save")
    @ResponseBody
    public ReturnMessageDTO saveProduct(@RequestBody ProductInteractiveDTO productInteractiveDTO){
        ProductMainPO productDTO = new ProductMainPO();
        // 1.构造商品基础信息
        this.genProductBasic(productDTO,productInteractiveDTO);
        // 2.构造商品口味属性信息
        this.genProductAttr(productDTO,productInteractiveDTO);
        // 3.构造商品多规格的的信息
        // 3.1 判断是否是规格商品，如果不是，则不用构造多规格数据
        /*if(productDTO.isSpec()) {
            this.genProductSpec(productDTO, productInteractiveDTO);
        }*/
        // 4.构造商品图片的信息
        this.genProductImg(productDTO,productInteractiveDTO);
        ReturnMessageDTO<ProductMainPO> returnMessage = new ReturnMessageDTO<>();
        try {
            productService.saveProduct(productDTO);
            // 同步商品到ES
            QueryMessageDTO qm = new QueryMessageDTO();
            qm.addCondition("uuid", QueryConditionEnum.EQ.name(), productDTO.getUuid());
            productService.syncProductToES(qm);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("菜品创建成功");
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote("菜品创建失败");
        }
        return returnMessage;
    }

    /**
     * 更新菜品信息
     *
     * @param dto
     * @return
     */
    @PostMapping("/updateProduct")
    @ResponseBody
    public ReturnMessageDTO updateProduct(@RequestBody ProductInteractiveDTO productInteractiveDTO){
        ProductMainPO productDTO = new ProductMainPO();
        // 1.构造商品基础信息
        this.genProductBasic(productDTO,productInteractiveDTO);
        // 2.构造商品口味属性信息
        this.genProductAttr(productDTO,productInteractiveDTO);
        // 3.构造商品多规格的的信息
        // 3.1 判断是否是规格商品，如果不是，则不用构造多规格数据
        /*if(productDTO.isSpec()){
            this.genProductSpec(productDTO,productInteractiveDTO);
        }*/
        // 4.构造商品图片的信息
        this.genProductImg(productDTO,productInteractiveDTO);
        ReturnMessageDTO<ProductMainPO> returnMessage = new ReturnMessageDTO<>();
        try {
            productService.updateProduct(productDTO);
            // 同步商品到ES
            QueryMessageDTO qm = new QueryMessageDTO();
            qm.addCondition("uuid", QueryConditionEnum.EQ.name(), productDTO.getUuid());
            productService.syncProductToES(qm);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("菜品更新成功");
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote("菜品更新失败");
        }
        return returnMessage;
    }

    
    private void genProductImg(ProductMainPO productDTO,ProductInteractiveDTO productInteractiveDTO){
        String[] mutiPicture = productInteractiveDTO.getMutipicture();
        List<ProductImagePO> list = new ArrayList<>();
        for (String  url: mutiPicture) {
            ProductImagePO img = new ProductImagePO();
            img.setBaseImg(url);
            // 进行图片压缩处理
            handleProductImage(img);
            list.add(img);
        }
        if(!list.isEmpty()){
            productDTO.setProductImageList(list);
            ProductImagePO productImagePO = list.get(0);
            if(productImagePO != null){
            	productDTO.setBigimg(productImagePO.getBigImg());
            	productDTO.setSmallimg(productImagePO.getSmallImg());
            }
        }
    }

    private void handleProductImage(ProductImagePO productImageDTO) {
        try {
            // 获取图片压缩比例
            int bigWidth = 800, bigHeight = 800;
            int centerWidth = 400, centerHeight = 400;
            int smallWidth = 200, smallHeight = 200;
            // 压缩质量 0-100
            Double quality = 80.0;
            // 主图不用处理，其他全部处理
            String baseImg = productImageDTO.getBaseImg();
            baseImg = baseImg.replace(imageUrl,localPath.substring(0,localPath.lastIndexOf("/")));
            // 将图片按等比压缩保存本地，然后上传服务器
            String[] filePreAndSufName = ImageUtils.getFilePreAndSufName(baseImg);
            String prefix = filePreAndSufName[1];
            String suffix = filePreAndSufName[2];
            String filePath = resizeFilePath;
            // 大图压缩
            String baseImg_big = filePath + "/" + prefix + "_big." + suffix;
            ImageUtils.resizeImage(baseImg, baseImg_big, bigWidth, bigHeight, quality);
            // 中图压缩
            String baseImg_center = filePath + "/" + prefix + "_center." + suffix;
            ImageUtils.resizeImage(baseImg, baseImg_center, centerWidth, centerHeight, quality);
            // 小图压缩
            String baseImg_small = filePath + "/" + prefix + "_small." + suffix;
            ImageUtils.resizeImage(baseImg, baseImg_small, smallWidth, smallHeight, quality);
            String bigImg = "";
            String centerImg = "";
            String smallImg = "";
            if(uploadToServer) {
                // 大图上传,并删除
                bigImg = fdfsIpPre + fastDFSClient.uploadFilePath(baseImg_big, suffix, true);
                // 中图上传,并删除
                centerImg = fdfsIpPre + fastDFSClient.uploadFilePath(baseImg_center, suffix, true);
                // 小图上传,并删除
                smallImg = fdfsIpPre + fastDFSClient.uploadFilePath(baseImg_small, suffix, true);
            }else{
                bigImg = localUploaderClient.uploadToLocal(baseImg_big);
                centerImg = localUploaderClient.uploadToLocal(baseImg_center);
                smallImg = localUploaderClient.uploadToLocal(baseImg_small);
            }
            productImageDTO.setBigImg(bigImg);
            productImageDTO.setCenterImg(centerImg);
            productImageDTO.setSmallImg(smallImg);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 构造商品多规格的的信息
     * @param productDTO
     * @param productInteractiveDTO
     */
    private void genProductSpec(ProductMainPO productDTO,ProductInteractiveDTO productInteractiveDTO){
        List<ProductSpecPO> list = productInteractiveDTO.getSpecData();
        if(!list.isEmpty()){
            productDTO.setProductSpecList(list);
        }
    }

    /**
     * 构造商品基础信息的方法
     * @param productDTO
     * @param productInteractiveDTO
     */
    private void genProductBasic(ProductMainPO productDTO,ProductInteractiveDTO productInteractiveDTO){
        productDTO.setUuid(productInteractiveDTO.getUuid());
        productDTO.setName(productInteractiveDTO.getName());
        productDTO.setCategoryUuid(productInteractiveDTO.getCategoryUuid());
        productDTO.setRecommendCategoryUuid(productInteractiveDTO.getRecommendCategoryUuid());
        productDTO.setNote(productInteractiveDTO.getNote());
        productDTO.setPrice(productInteractiveDTO.getPrice());
        productDTO.setPromotionType(productInteractiveDTO.getPromotionType());
        productDTO.setPromotionPrice(productInteractiveDTO.getPromotionPrice());
        productDTO.setLunchboxPrice(productInteractiveDTO.getLunchboxPrice());
        productDTO.setState(productInteractiveDTO.isState());
        productDTO.setTag(productInteractiveDTO.getTag());
        productDTO.setSpec(productInteractiveDTO.isSpec());
        productDTO.setVendorUuid(productInteractiveDTO.getVendorUuid());
        productDTO.setIntegral(productInteractiveDTO.getIntegral());
        productDTO.setPromotionRate(productInteractiveDTO.getPromotionRate());
        VendorPO vendor = vendorService.getByUuid(productInteractiveDTO.getVendorUuid());
        productDTO.setVendorName(vendor.getVendorName());
    }

    /**
     * 构造商品属性信息的方法（包括规格和非规格属性）
     * @param productDTO
     * @param productInteractiveDTO
     */
    private void genProductAttr(ProductMainPO productDTO,ProductInteractiveDTO productInteractiveDTO){
        List<ProductAttrPO> attrList = productInteractiveDTO.getAttrs();
        Iterator<ProductAttrPO> iterator = attrList.iterator();
        while(iterator.hasNext()){
            ProductAttrPO attr = iterator.next();
            if(!attr.isStatus()){
                iterator.remove();
            }
        }
        productDTO.setProductAttrList(attrList);
    }
    
    /**
     * 删除菜品
     *
     * @param deleteUuids
     * @return
     */
    @PostMapping({"/delete"})
    @ResponseBody
    public ReturnMessageDTO<ProductMainPO> delete(@RequestBody List<String> idList) {
        ReturnMessageDTO<ProductMainPO> returnMessage = new ReturnMessageDTO<>();
        try {
            productService.deleteProducts(idList);
            // 删除ES里的商品信息
            productService.deleteProductFromES(idList);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("删除成功");
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.ERROR.getReturnCode());
            returnMessage.setReturnNote(e.getMessage());
        }
        return returnMessage;
    }

    /**
     * 分页查询菜品列表
     *
     * @param
     * @return
     */
    @PostMapping("/list")
    @ResponseBody
    public ReturnMessageDTO<List<ProductMainPO>> list(@RequestBody QueryMessageDTO qm) {
        List<ProductMainPO> list = productService.getProductInfoFromES(qm);
        int count = productService.getCountFromES(qm);
        ReturnMessageDTO<List<ProductMainPO>> returnMessageDTO = new ReturnMessageDTO<>();
        returnMessageDTO.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
        returnMessageDTO.setReturnNote("查询成功");
        returnMessageDTO.setReturnMessage(list);
        returnMessageDTO.setPager(new Pager(qm.getPageShow(), qm.getQueryPage(), count));
        return returnMessageDTO;
    }


    /**
     * 批量上架
     *
     * @param uuids
     * @return
     */
    @PostMapping("/onShelves")
    @ResponseBody
    public ReturnMessageDTO<String> onShelves(@RequestBody List<String> idList) {
        ReturnMessageDTO<String> returnMessage = new ReturnMessageDTO<>();
        try {
        	productService.onShelves(idList);
            // 同步商品到ES
            QueryMessageDTO qm = new QueryMessageDTO();
            qm.addCondition("uuid", QueryConditionEnum.IN.name(), idList);
            productService.syncProductToES(qm);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("菜品上架成功");
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote("菜品上架失败");
        }
        return returnMessage;
    }

    /**
     * 批量下架
     *
     * @param uuids
     * @return
     */
    @PostMapping("/offShelves")
    @ResponseBody
    public ReturnMessageDTO<String> offShelves(@RequestBody List<String> idList) {
        ReturnMessageDTO<String> returnMessage = new ReturnMessageDTO<>();
        try {
        	productService.offShelves(idList);
            // 同步商品到ES
            QueryMessageDTO qm = new QueryMessageDTO();
            qm.addCondition("uuid", QueryConditionEnum.IN.name(), idList);
            productService.syncProductToES(qm);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("菜品下架成功");
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote("菜品下架失败");
        }
        return returnMessage;
    }

    @PostMapping("/sellOut")
    @ResponseBody
    public ReturnMessageDTO<String> sellOut(@RequestBody List<String> idList) {
        ReturnMessageDTO<String> returnMessage = new ReturnMessageDTO<>();
        try {
        	productService.sellOut(idList);
            // 同步商品到ES
            QueryMessageDTO qm = new QueryMessageDTO();
            qm.addCondition("uuid", QueryConditionEnum.IN.name(), idList);
            productService.syncProductToES(qm);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("菜品售罄");
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote(e.getMessage());
        }
        return returnMessage;
    }

    @PostMapping("/supply")
    @ResponseBody
    public ReturnMessageDTO<String> supply(@RequestBody List<String> idList) {
        ReturnMessageDTO<String> returnMessage = new ReturnMessageDTO<>();
        try {
        	productService.supply(idList);
            // 同步商品到ES
            QueryMessageDTO qm = new QueryMessageDTO();
            qm.addCondition("uuid", QueryConditionEnum.IN.name(), idList);
            productService.syncProductToES(qm);
            returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
            returnMessage.setReturnNote("菜品补货成功");
        } catch (Exception e) {
            returnMessage.setReturnCode(ReturnCodeEnum.FAIL.getReturnCode());
            returnMessage.setReturnNote(e.getMessage());
        }
        return returnMessage;
    }

    /**
     * 根据id查询菜品
     *
     * @param id
     * @return
     */
    @PostMapping("/get/{id}")
    @ResponseBody
    public ReturnMessageDTO<ProductMainPO> getById(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) {
        ProductMainPO productMainPO = productService.getByUuid(id);
        //List<ProductSpecPO> specList = productSpecService.getSpecsByMainUuid(id);
        List<ProductAttrPO> attrList = productAttrService.getAttrsByMainUuid(id);
        List<ProductImagePO> imageList = productImageService.getImagesByMainUuid(id);
        //productMainPO.setProductSpecList(specList);
        productMainPO.setProductAttrList(attrList);
        productMainPO.setProductImageList(imageList);
        if (null != imageList && imageList.size() > 0) {
            productMainPO.setSmallimg(imageList.get(0).getSmallImg());
        }
        ProductCategoryPO productCategoryPO = productCategoryService.getByUuid(productMainPO.getCategoryUuid());
        if (null != productCategoryPO) {
            productMainPO.setCategoryName(productCategoryPO.getName());
        }
        ReturnMessageDTO<ProductMainPO> returnMessage = new ReturnMessageDTO<>();
        returnMessage.setReturnCode(ReturnCodeEnum.SUCCESS.getReturnCode());
        returnMessage.setReturnMessage(productMainPO);
        returnMessage.setReturnNote("获取商品详情成功");
        return returnMessage;
    }


	@Override
	public String toEdit(Model model, @PathVariable(value = "id") String id, HttpServletRequest request) {
		ProductMainPO dto = productService.toEdit(id);
		model.addAttribute("dto", dto);
		this.buildEditPageData(model, dto, request);
		return "system/product/ProductEdit";
	}

   
    
}
